import { GameState, GameConfig, Player, GamePhase, SpaceType, GameError, GameErrorType } from '../types';
import { boardGenerator } from './BoardGenerator';
import { propertyManager } from './PropertyManager';
import { eventEngine } from './EventEngine';
import { getThemeById, getDefaultTheme } from '../data/themes';
import { getShuffledChanceCards, getShuffledCommunityCards } from '../data/eventCards';

export class GameManager {
  /**
   * 初始化游戏
   */
  initializeGame(config: GameConfig, players: Player[]): GameState {
    const theme = getThemeById(config.theme) || getDefaultTheme();
    const board = boardGenerator.generateBoard(theme);
    
    // 初始化事件卡
    const chanceCards = getShuffledChanceCards();
    const communityCards = getShuffledCommunityCards();
    eventEngine.initializeDecks(chanceCards, communityCards);

    // 初始化玩家
    const initializedPlayers = players.map(p => ({
      ...p,
      position: 0,
      money: config.initialMoney,
      properties: [],
      items: [],
      isActive: true,
      isBankrupt: false,
      abilityLastUsed: 0,
      canReroll: p.character.id === 'lucky-charm',
    }));

    const gameState: GameState = {
      id: `game-${Date.now()}`,
      players: initializedPlayers,
      board,
      currentPlayerIndex: 0,
      turn: 1,
      phase: GamePhase.PLAYING,
      chanceCards,
      communityCards,
      tradeOffers: [],
      config,
      history: [],
      winner: null,
    };

    return gameState;
  }

  /**
   * 开始回合
   */
  startTurn(gameState: GameState): void {
    const currentPlayer = gameState.players[gameState.currentPlayerIndex];
    
    // 重置幸运女神的重投能力
    if (currentPlayer.character.id === 'lucky-charm') {
      currentPlayer.canReroll = true;
    }

    eventEngine.emit('turn:start', { player: currentPlayer, gameState });
  }

  /**
   * 掷骰子
   */
  rollDice(): number {
    const die1 = Math.floor(Math.random() * 6) + 1;
    const die2 = Math.floor(Math.random() * 6) + 1;
    return die1 + die2;
  }

  /**
   * 移动玩家
   */
  movePlayer(playerId: string, steps: number, gameState: GameState): void {
    const player = gameState.players.find(p => p.id === playerId);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    const oldPosition = player.position;
    let newPosition = (oldPosition + steps) % 40;

    // 旅行者可以选择后退
    if (player.character.id === 'traveler' && steps < 0) {
      newPosition = (oldPosition + steps + 40) % 40;
    }

    // 检查是否经过起点
    if (newPosition < oldPosition || (oldPosition + steps >= 40)) {
      this.passGo(player, gameState);
    }

    player.position = newPosition;

    // 触发位置事件
    this.handleSpaceAction(playerId, gameState);
  }

  /**
   * 经过起点
   */
  private passGo(player: Player, gameState: GameState): void {
    let bonus = gameState.config.startBonus;

    // 银行家被动能力：额外50%
    if (player.character.id === 'banker') {
      bonus = Math.floor(bonus * 1.5);
    }

    player.money += bonus;
  }

  /**
   * 处理位置事件
   */
  handleSpaceAction(playerId: string, gameState: GameState): void {
    const player = gameState.players.find(p => p.id === playerId);
    if (!player) return;

    const space = gameState.board[player.position];

    // 检查是否有幸运护盾
    const luckyShieldIndex = player.items.findIndex(item => item.id === 'lucky-shield');
    if (luckyShieldIndex !== -1) {
      player.items.splice(luckyShieldIndex, 1);
      return; // 免除所有费用
    }

    switch (space.type) {
      case SpaceType.PROPERTY:
        if (space.property) {
          if (space.property.owner === null) {
            // 无主地块，可以购买
            eventEngine.emit('space:property-available', { player, property: space.property, gameState });
          } else if (space.property.owner !== playerId) {
            // 支付租金
            propertyManager.payRent(playerId, space.property.id, gameState);
          }
        }
        break;

      case SpaceType.CHANCE:
        const chanceCard = eventEngine.drawEventCard('chance');
        eventEngine.executeEvent(chanceCard, player, gameState);
        break;

      case SpaceType.COMMUNITY:
        const communityCard = eventEngine.drawEventCard('community');
        eventEngine.executeEvent(communityCard, player, gameState);
        break;

      case SpaceType.GO_TO_JAIL:
        player.position = 10; // 监狱位置
        break;

      case SpaceType.TAX:
        const taxAmount = space.position === 4 ? 200 : 100;
        player.money -= taxAmount;
        break;
    }
  }

  /**
   * 结束回合
   */
  endTurn(gameState: GameState): void {
    const currentPlayer = gameState.players[gameState.currentPlayerIndex];
    
    // 检查破产
    if (currentPlayer.money < 0) {
      this.handleBankruptcy(currentPlayer.id, gameState);
    }

    // 检查胜利条件
    const winner = this.checkWinCondition(gameState);
    if (winner) {
      gameState.winner = winner.id;
      gameState.phase = GamePhase.GAME_OVER;
      return;
    }

    // 移动到下一个玩家
    do {
      gameState.currentPlayerIndex = (gameState.currentPlayerIndex + 1) % gameState.players.length;
    } while (gameState.players[gameState.currentPlayerIndex].isBankrupt);

    // 如果回到第一个玩家，增加回合数
    if (gameState.currentPlayerIndex === 0 || 
        gameState.players.slice(0, gameState.currentPlayerIndex).every(p => p.isBankrupt)) {
      gameState.turn += 1;
    }

    this.startTurn(gameState);
  }

  /**
   * 处理破产
   */
  private handleBankruptcy(playerId: string, gameState: GameState): void {
    const player = gameState.players.find(p => p.id === playerId);
    if (!player) return;

    player.isBankrupt = true;
    player.isActive = false;

    // 将所有地块归还银行
    player.properties.forEach(propId => {
      const property = gameState.board.find(s => s.property?.id === propId)?.property;
      if (property) {
        property.owner = null;
        property.level = 0;
        property.mortgaged = false;
      }
    });

    player.properties = [];
    player.items = [];
  }

  /**
   * 检查胜利条件
   */
  checkWinCondition(gameState: GameState): Player | null {
    const activePlayers = gameState.players.filter(p => !p.isBankrupt);

    // 只剩一个玩家
    if (activePlayers.length === 1) {
      return activePlayers[0];
    }

    // 时间限制
    if (gameState.config.winCondition === 'timeLimit' && 
        gameState.config.timeLimit && 
        gameState.turn >= gameState.config.timeLimit) {
      return this.getRichestPlayer(activePlayers, gameState);
    }

    // 资产目标
    if (gameState.config.winCondition === 'targetAssets' && 
        gameState.config.targetAssets) {
      const richest = this.getRichestPlayer(activePlayers, gameState);
      const totalAssets = this.calculateTotalAssets(richest, gameState);
      if (totalAssets >= gameState.config.targetAssets) {
        return richest;
      }
    }

    return null;
  }

  /**
   * 获取最富有的玩家
   */
  private getRichestPlayer(players: Player[], gameState: GameState): Player {
    return players.reduce((richest, current) => {
      const richestAssets = this.calculateTotalAssets(richest, gameState);
      const currentAssets = this.calculateTotalAssets(current, gameState);
      return currentAssets > richestAssets ? current : richest;
    });
  }

  /**
   * 计算总资产
   */
  calculateTotalAssets(player: Player, gameState: GameState): number {
    let total = player.money;

    player.properties.forEach(propId => {
      const property = gameState.board.find(s => s.property?.id === propId)?.property;
      if (property) {
        total += property.price;
        total += property.upgradeCost * property.level;
      }
    });

    return total;
  }
}

// 导出单例实例
export const gameManager = new GameManager();
